/*
如果你的编译不通过的话，请在项目右键->属性->链接器->输入->附加依赖项中添加如下lib：
d2d1.lib
dxguid.lib
Dwrite.lib
user32.lib
由于这是窗口程序，所以你可能还需要将项目右键->属性->配置属性->链接器->系统中的【子系统】设置为 窗口
*/
#include <math.h>
#include <time.h>
#include "DrawApp.h"
#define WIDTH 1080
#define HEIGHT 720
DrawDemo Draw;
RECT winp;//窗口坐标
POINT moup;//鼠标坐标
const float GameFrameTime = 0.7f;
const float ZULI = 0.97f;

#define FASHESUDU 50//子弹发射的速度，越小越快
#define SHENGCHENGSUDU 1000//敌方方块的生成速度，越小越快
#define LIZISHULIANG 50//敌方方块被打中后产生的粒子数量
#define DIFANGLIFE 1//敌方方块的生命(0是1，1是2 以此类推)

//玩家
class player {
public:
	player(float x, float y) :m_x(x), m_y(y) {};
	void revolve(float angle) {
		float x = sin(angle);
		float y = cos(angle);
		m_rx = x * 20 + (WIDTH / 2);
		m_ry = y * 20 + (HEIGHT / 2);
	};
	void draw() {
		Draw.setLineColor(D2D1::ColorF(D2D1::ColorF::White));
		Draw.setFillColor(D2D1::ColorF(D2D1::ColorF::White));
		Draw.DrawEllipse(D2D1::Ellipse(D2D1::Point2F(m_x, m_y), m_r, m_r), 1.0f);
		Draw.DrawLine(m_x, m_y, m_rx, m_ry, 1.0f);
	};

	float m_x;
	float m_y;
	float m_rx;//玩家面朝方向
	float m_ry;
private:
	float m_r = 10;
};
//子弹
class bullet {
public:
	//子弹构造函数（子弹x，y，dx，dy，生命）
	bullet(float x, float y, float dx, float dy, float life) :m_x(x), m_y(y), m_dx(dx), m_dy(dy), m_life(life) {}
	//子弹移动
	void move() {
		m_life -= 0.03f;
		m_x = m_x + m_dx * GameFrameTime;
		m_y = m_y + m_dy * GameFrameTime;
	}
	//子弹碰撞
	bool bump() {
		if (m_x > WIDTH - 10 || m_x < 0) {
			m_dx = m_dx * -1;
		}
		if (m_y > HEIGHT - 35 || m_y < 0) {
			m_dy = m_dy * -1;
		}
		if (m_life <= 0) {
			f = 1;
			return 1;
		}
		return 0;
	}
	//画子弹
	void draw() {
		if (m_life < 1.0f) {
			color.a = m_life;
		}
		Draw.setLineColor(color);
		Draw.setFillColor(color);
		Draw.DrawEllipse(D2D1::Ellipse(D2D1::Point2F(m_x, m_y), m_r, m_r), 1.0f);
		Draw.FillEllipse(D2D1::Ellipse(D2D1::Point2F(m_x, m_y), m_r, m_r));
	}
	
	float m_x;
	float m_y;
	float m_dx;
	float m_dy;
	float m_r = 5.0f;
	float m_life = 0;//当前生命
	bool f = 0;//销毁标志
	D2D1_COLOR_F color = ColorF(1.0f, 1.0f, 1.0f, 1.0f);
};
//敌方
class difang {
public:
	difang(float x, float y, float dx, float dy) {
		m_x = x; m_y = y; m_dx = dx, m_dy = dy;
	};
	void draw() {
		Draw.setLineColor(color);
		Draw.setFillColor(color);
		Draw.DrawRect(D2D1::RoundedRect(D2D1::RectF(m_x, m_y, m_w + m_x, m_w + m_y), 0.0f, 0.0f), 1.0f);
		Draw.FillRect(D2D1::RoundedRect(D2D1::RectF(m_x, m_y, m_w + m_x, m_w + m_y), 0.0f, 0.0f));
	}
	bool bump() {

		return 0;
	}
	void move() {
		if (m_x > WIDTH - 10 || m_x < 0) {
			m_dx = m_dx * -1;
		}
		if (m_y > HEIGHT - 35 || m_y < 0) {
			m_dy = m_dy * -1;
		}
		m_x = m_x + m_dx * GameFrameTime;
		m_y = m_y + m_dy * GameFrameTime;
	}
	float m_w = 20.0f;
	float m_x;
	float m_y;
	float m_dx;
	float m_dy;
	int m_life = DIFANGLIFE;
	bool f = 0;//销毁标志
	D2D1_COLOR_F color = ColorF(1.0f, 0, 0, 1.0f);
};
//粒子
class lizi {
public:
	lizi(float x, float y) {
		m_x = x; m_y = y;
		float color_r = rand() % (99 + 1) / (float)(99 + 1);
		float color_g = rand() % (99 + 1) / (float)(99 + 1);
		float color_b = rand() % (99 + 1) / (float)(99 + 1);
		color = ColorF(color_r, color_g, color_b, 1.0f);
		m_dx = rand() % 30 - 15;
		m_dy = rand() % 30 - 15;
		m_w = rand() % 10 + 5;
	}
	void move() {
		m_life -= 0.03f;
		if (m_life < 1.0f) {
			color.a = m_life;
		}
		if (m_life <= 0.0f) {
			f = 1;
		}
		if (m_x > WIDTH - 10 || m_x < 0) {
			m_dx = m_dx * -1;
		}
		if (m_y > HEIGHT - 35 || m_y < 0) {
			m_dy = m_dy * -1;
		}
		m_dx *= ZULI;
		m_dy *= ZULI;
		m_x = m_x + m_dx * GameFrameTime;
		m_y = m_y + m_dy * GameFrameTime;
	}
	void draw() {
		Draw.setLineColor(color);
		Draw.setFillColor(color);
		Draw.DrawRect(D2D1::RoundedRect(D2D1::RectF(m_x, m_y, m_w + m_x, m_w + m_y), 0.0f, 0.0f), 1.0f);
		Draw.FillRect(D2D1::RoundedRect(D2D1::RectF(m_x, m_y, m_w + m_x, m_w + m_y), 0.0f, 0.0f));
	}
	float m_x;
	float m_y;
	float m_dx;
	float m_dy;
	float m_w;
	float m_life = 2.0f;
	bool f = 0;
	D2D1_COLOR_F color;
};

player* play;
std::vector<bullet> m_bulletlist;
std::vector<difang> m_difanglist;
std::vector<lizi>   m_lizilist;
DWORD t1, t2, t3;
bool iii = 0;
void Gameloop();
void GameInit();

int WINAPI WinMain(_In_ HINSTANCE hThisInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR IpszCmdLine,	_In_ int nCmdShow) {
	srand((unsigned)time(NULL));
	Draw.CreatWindows(WIDTH, HEIGHT, hThisInstance, hPrevInstance, IpszCmdLine, nCmdShow, Gameloop, GameInit);
}

void Gamedraw() {
	Draw.begindraw();

	Draw.Clear(0, 0, 0, 1.0f);
	play->draw();
	int moux = moup.x - winp.left;//鼠标x坐标
	int mouy = moup.y - winp.top; //鼠标y坐标
	for (auto it = m_bulletlist.begin(); it != m_bulletlist.end(); it++) {
		(*it).draw();
	}
	for (auto it = m_difanglist.begin(); it != m_difanglist.end(); it++) {
		(*it).draw();
	}
	for (auto it = m_lizilist.begin(); it != m_lizilist.end(); it++) {
		(*it).draw();
	}
	wchar_t ch[200] = { 0 };
	swprintf_s(ch, L"玩家rx: %f ry: %f 子弹数量: %d 敌方数量: %d 粒子数量: %d",
		play->m_rx - WIDTH / 2, play->m_ry - HEIGHT / 2, (int)m_bulletlist.size(), (int)m_difanglist.size(), (int)m_lizilist.size());
	Draw.setTextColor(ColorF(1.0f, 1.0f, 1.0f, 1.0f));
	Draw.DrawText_(ch, Rect(0, 0, WIDTH, HEIGHT), 15.0f);

	Draw.enddraw();
}
void Gameupdata() {
	t1 = GetTickCount();
	if (t1 - t2 > FASHESUDU && iii == 1) {//隔一段时间生成子弹 第一次生成的子弹不要
		m_bulletlist.push_back(bullet(play->m_x, play->m_y, play->m_rx - WIDTH / 2, play->m_ry - HEIGHT / 2, 2.5f));
		t2 = t1;
	}
	if (t1 - t3 > SHENGCHENGSUDU) {
		m_difanglist.push_back(difang(800, 300, rand() % 20 - 10, rand() % 20 - 10));
		t3 = t1;
	}
	iii = 1;
	for (auto it = m_bulletlist.begin(); it != m_bulletlist.end();) {
		if (it->bump() || it->f == 1) {
			it = m_bulletlist.erase(it);
		}
		else {
			it->move();
			it++;
		}
	}
	for (auto it = m_difanglist.begin(); it != m_difanglist.end();) {
		if (it->bump() || it->f == 1) {
			it = m_difanglist.erase(it);
		}
		else {
			it->move();
			it++;
		}
	}
	//碰撞检测
	for (auto it = m_bulletlist.begin(); it != m_bulletlist.end(); it++) {
		for (auto i = m_difanglist.begin(); i != m_difanglist.end(); i++) {
			//float jvli = sqrt((it->m_x - (i->m_x + 15)) * (it->m_x - (i->m_x + 15)) + (it->m_y - (i->m_y + 15)) * (it->m_y - (i->m_y + 15)));
			float topA = it->m_y - it->m_r;
			float bottomA = it->m_y + it->m_r;
			float leftA = it->m_x - it->m_r;
			float rightA = it->m_x + it->m_r;

			float topB = i->m_y;
			float bottomB = i->m_y + i->m_w;
			float leftB = i->m_x;
			float rightB = i->m_x + i->m_w;
			
			if (leftA < rightB && rightA > leftB && topA < bottomB && bottomA > topB) {
				it->f = 1;
				if (!i->m_life) {
					i->f = 1;
					for (size_t j = 0; j < LIZISHULIANG; j++) {
						m_lizilist.push_back(lizi(i->m_x, i->m_y));
					}
				}
				--i->m_life;
			}
		}
	}
	for (auto it = m_lizilist.begin(); it != m_lizilist.end();) {
		if (it->f == 1) {
			it = m_lizilist.erase(it);
		}
		else {
			it->move();
			it++;
		}
	}
	GetWindowRect(Draw.GetHwnd(), &winp);
	GetCursorPos(&moup);
	int moux = moup.x - winp.left - 9;//鼠标x坐标
	int mouy = moup.y - winp.top - 30; //鼠标y坐标
	float xx = moux - WIDTH / 2;
	float yy = mouy - HEIGHT / 2;
	float ab = xx * 0.0f + 1.0f * yy;
	ab = ab / (1.0f * sqrt(xx * xx + yy * yy));
	ab = acos(ab);
	if (xx > 0)
		play->revolve(ab);
	else
		play->revolve(-ab);
}
void Gameloop() {
	Gameupdata();
	Gamedraw();
}
void GameInit() {
	t1 = t2 = t3 = GetTickCount();  //获取电脑开机时间
	play = new player(WIDTH / 2, HEIGHT / 2);

}